"""
https://leetcode.cn/problems/min-stack/description/

解题思路：https://algo.itcharge.cn/Solutions/0100-0199/min-stack/

155. 最小栈
已解答
中等
相关标签
相关企业
提示
设计一个支持 push ，pop ，top 操作，并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。
 

示例 1:

输入：
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出：
[null,null,null,null,-3,null,0,-2]

解释：
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.
 

提示：

-231 <= val <= 231 - 1
pop、top 和 getMin 操作总是在 非空栈 上调用
push, pop, top, and getMin最多被调用 3 * 104 次
"""

class MinStack:
    """
    核心思想是，在利用栈的操作只能单线程执行，同时维护一个对应操作时的最小元素
    """

    def __init__(self):
        self.stack=[]
        self.minStack=[]
        pass
        

    def push(self, val: int) -> None:
        self.stack.append(val)
        if len(self.minStack)==0:
            self.minStack.append(val)
        else:
            self.minStack.append(min(self.minStack[-1],val))
        pass
        

    def pop(self) -> None:
        if len(self.stack)==0:
            return None
        top_val = self.stack.pop()
        self.minStack.pop()
        return top_val
        pass
        

    def top(self) -> int:
        return self.stack[-1]
        pass
        

    def getMin(self) -> int:
        return self.minStack[-1]
        


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
if __name__=='__main__':
    minStack=MinStack()
    while True:
        print('input order:')
        order=input();
        if order.startswith('push'):
            minStack.push(int(order.split(' ')[-1]))
            print('push success')
        elif order.startswith('pop'):
            val=minStack.pop()
            print(f'pop success:{val}')
        elif order=='min':
            print(f'min:{minStack.getMin()}')
        elif order=='top':
            print(f'top:{minStack.top()}')
        else:
            break
